package com.yanqu.road.server.manager.activity.jiuzhou.activity;

import com.yanqu.road.entity.activity.ActivityInfo;
import com.yanqu.road.entity.activity.jiuzhou.config.JiuZhouConfig;
import com.yanqu.road.entity.activity.jiuzhou.config.JiuZhouRoundConfig;
import com.yanqu.road.entity.activity.jiuzhou.config.JiuZhouSkillConfig;
import com.yanqu.road.entity.enums.activity.jiuzhou.eJiuZhouBigSkillType;
import com.yanqu.road.logic.bussiness.activity.JiuZhouBussiness;
import com.yanqu.road.logic.bussiness.servercenter.ActivityBussiness;
import com.yanqu.road.utils.RandomHelper;
import com.yanqu.road.utils.date.DateHelper;
import com.yanqu.road.utils.property.Property;
import com.yanqu.road.utils.property.PropertyHelper;
import com.yanqu.road.utils.string.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.util.*;

/**
 * 九州棋局基类、配置
 */
public class CrossJiuZhouBaseActivity {

    /**
     * 九州调试模式
     */
    protected static boolean debug = false;

    protected static Logger logger = LogManager.getLogger(CrossJiuZhouBaseActivity.class.getName());

    protected RandomHelper randomHelper = new RandomHelper();

    /**
     * 活动大锁
     */
    protected final Object lock = new Object();

    /**
     * 活动配置
     */
    protected JiuZhouConfig config;

    public CrossJiuZhouBaseActivity(ActivityInfo activityInfo) {
        reloadConfig(activityInfo);
    }

    public void reloadConfig(ActivityInfo activityInfo) {
        // 读配置
        JiuZhouConfig tempConfig = new JiuZhouConfig();
        tempConfig.setActivityInfo(activityInfo);
        // 加载其他配置
        tempConfig.setRoundConfigMap(JiuZhouBussiness.getJiuZhouRoundConfigMap(activityInfo.getActivityId()));
        tempConfig.initConfig(ActivityBussiness.getActivityConfigMap(Collections.singletonList(activityInfo.getActivityId())).get(activityInfo.getActivityId()));
        for (JiuZhouRoundConfig roundConfig : tempConfig.getRoundConfigMap().values()) {
            String time = roundConfig.getTime();
            List<Integer> integerList = StringUtils.stringToIntegerList(time, "\\|");
            roundConfig.setTimeList(integerList);

            List<String> fightParamList = StringUtils.stringToStringList(roundConfig.getFightParam(), "#");
            roundConfig.setInitHp(Integer.parseInt(fightParamList.get(0)));
            List<List<Integer>> attackDamageParamList = new ArrayList<>();
            List<String> fightParamList1 = StringUtils.stringToStringList(fightParamList.get(1), "\\|");
            for (String fightParamList2 : fightParamList1) {
                List<Integer> fightParamList3 = StringUtils.stringToIntegerList(fightParamList2, ";");
                attackDamageParamList.add(fightParamList3);
            }
            roundConfig.setAttackDamageParamList(attackDamageParamList);
        }
        tempConfig.setSkillConfigMap(JiuZhouBussiness.getJiuZhouSkillConfigMap(activityInfo.getActivityId()));
        config = tempConfig;
    }

    public JiuZhouConfig getConfig() {
        return config;
    }

    /**
     * 活动开始时间+分钟转化为时间戳
     */
    public long getTimeStampAfterBegin(int minute){
        return config.getActivityInfo().getBeginTime() * DateHelper.SECOND_MILLIONS + (long) minute * DateHelper.MINUTE_MILLIONS;
    }


    /**
     * 通过轮次id获取轮次配置
     */
    public JiuZhouRoundConfig getJiuZhouRoundConfigById(int roundId){
        Map<Integer, JiuZhouRoundConfig> roundConfigMap = config.getRoundConfigMap();
        if (roundConfigMap == null || roundConfigMap.isEmpty()) {
            logger.error("九州棋局轮次配置为空, activityId:{}", config.getActivityInfo().getActivityId());
            return null;
        }
        return roundConfigMap.get(roundId);
    }

    /**
     * 随机一个技能
     *
     * @param skillBigType 技能类型
     */
    public JiuZhouSkillConfig randomSkill(int skillBigType) {
        int totalWeight = 0;
        for (JiuZhouSkillConfig skillConfig : config.getSkillConfigMap().values()) {
            if (skillConfig == null || skillConfig.getType() != skillBigType) {
                continue;
            }
            totalWeight += skillConfig.getWeight();
        }
        int randomValue = randomHelper.next(0, totalWeight);
        int tempValue = 0;
        for (JiuZhouSkillConfig skillConfig : config.getSkillConfigMap().values()) {
            if (skillConfig == null || skillConfig.getType() != skillBigType) {
                continue;
            }
            tempValue += skillConfig.getWeight();
            if (tempValue > randomValue) {
                return skillConfig;
            }
        }
        return null;
    }

    /**
     * 随机天时
     * 1、给赛场中的每个玩家随机编号1/2/3/4/5/6/7/8，数字不重复。
     * *不要按赚钱/排名等依据来定编号
     * 2、每两个玩家的编号相加，求该值除以7的余数
     * *例：玩家2和玩家5，余数=0
     * 3、根据余数分配天时
     * 1=士
     * 2=农
     * 3=工
     * 4=商
     * 5=侠
     * 6=五行均衡
     * 0=随机
     */
    public JiuZhouSkillConfig randomSkill1(int num1, int num2) {
        int skillId = (num1 + num2) % 7;
        if (skillId == 0) {
            skillId = randomHelper.next(1, 7);
        }
        return config.getSkillConfig(skillId);
    }

    /**
     * 随机一个技能
     *
     * @param skillBigType 技能类型
     */
    public JiuZhouSkillConfig randomSkillExclude(int skillBigType, List<Integer> excludeSkillIdList) {
        int totalWeight = 0;
        for (JiuZhouSkillConfig skillConfig : config.getSkillConfigMap().values()) {
            if (skillConfig == null || skillConfig.getType() != skillBigType || excludeSkillIdList.contains(skillConfig.getId())) {
                continue;
            }
            totalWeight += skillConfig.getWeight();
        }
        int randomValue = randomHelper.next(0, totalWeight);
        int tempValue = 0;
        for (JiuZhouSkillConfig skillConfig : config.getSkillConfigMap().values()) {
            if (skillConfig == null || skillConfig.getType() != skillBigType || excludeSkillIdList.contains(skillConfig.getId())) {
                continue;
            }
            tempValue += skillConfig.getWeight();
            if (tempValue > randomValue) {
                return skillConfig;
            }
        }
        return null;
    }

    /**
     * 获取士气鼓舞技能
     */
    public int getSkillId4() {
        for (JiuZhouSkillConfig skillConfig : config.getSkillConfigMap().values()) {
            if (skillConfig.getType() == eJiuZhouBigSkillType.Skill4.getValue()) {
                return skillConfig.getId();
            }
        }
        return 0;
    }

    /**
     * 计算伤害
     *
     * @param round   轮次
     * @param hpRadio 血量千分比
     */
    protected int calcAttackDamage(int round, int hpRadio) {
        JiuZhouRoundConfig roundConfig = getJiuZhouRoundConfigById(round);
        if (roundConfig == null) {
            return 0;
        }
        int attackDamage = 0;
        for (List<Integer> list : roundConfig.getAttackDamageParamList()) {
            if (hpRadio > list.get(0)) {
                attackDamage = list.get(1);
            }
        }
        // 保底伤害1
        return Math.max(1, attackDamage);
    }


    /**
     * 获取胜利积分
     */
    public long getBattleScore(int round, int rankNum) {
        JiuZhouRoundConfig roundConfig = getJiuZhouRoundConfigById(round);
        if (roundConfig == null) {
            return 0;
        }
        List<Long> list = StringUtils.stringToLongList(roundConfig.getScore(), "\\|");
        if (rankNum > list.size()) {
            return 0;
        }
        return list.get(Math.max(0, Math.min(list.size() - 1, rankNum - 1)));
    }

    /**
     * 获取排名奖励
     */
    public Property getBattleReward(int round, int zoneType, int rankNum) {
        JiuZhouRoundConfig roundConfig = getJiuZhouRoundConfigById(round);
        if (roundConfig == null) {
            return new Property();
        }
        List<String> list = StringUtils.stringToStringList(roundConfig.getReward(), "-");
        if (zoneType > list.size()) {
            return new Property();
        }
        String zoneReward = list.get(Math.max(0, Math.min(list.size() - 1, zoneType - 1)));
        List<String> list2 = StringUtils.stringToStringList(zoneReward, "@");
        if (rankNum > list2.size()) {
            return new Property();
        }
        return PropertyHelper.parseNewStringToProperty(list2.get(Math.max(0, Math.min(list2.size() - 1, rankNum - 1))));
    }

    /**
     * 获取伤害倍率(百分比)
     */
    public int calcFightMultiple(int gameRound) {
        int maxMultiple = 100;
        for (List<Integer> list : config.getFightMultipleParamList()) {
            if (gameRound >= list.get(0) && list.get(1) >= maxMultiple) {
                maxMultiple = list.get(1);
            }
        }
        return maxMultiple;
    }
}
